package visiopuce.service.document;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.swt.widgets.Display;

import visiopuce.ApplicationContexte;
import visiopuce.objets.Analyse;
import visiopuce.objets.Champ;
import visiopuce.objets.Personne;
import visiopuce.objets.Prelevement;
import visiopuce.objets.Puce;
import visiopuce.objets.RenduBiomol;
import visiopuce.objets.Resultat;
import visiopuce.objets.Utilisateur;
import visiopuce.objets.VerifBiomol;
import visiopuce.objets.VerifBiomolDoc;
import visiopuce.service.AnalyseServiceImpl;
import visiopuce.service.PersonneServiceImpl;
import visiopuce.service.PrelevementServiceImpl;
import visiopuce.service.PuceServiceImpl;
import visiopuce.service.ResultatServiceImpl;
import fr.opensagres.xdocreport.core.XDocReportException;
import fr.opensagres.xdocreport.document.IXDocReport;
import fr.opensagres.xdocreport.document.registry.XDocReportRegistry;
import fr.opensagres.xdocreport.template.IContext;
import fr.opensagres.xdocreport.template.TemplateEngineKind;

public class ResultatBiomol {

	public String createDocument(Resultat r) {
		String nomFichierout = "";
		try {

			boolean creer = true;
			InputStream in = new FileInputStream(new File(ApplicationContexte.REPERTOIRE_MODEL + "resulatBiomol.docx"));
			IXDocReport report = XDocReportRegistry.getRegistry().loadReport(in, TemplateEngineKind.Velocity);
			Analyse analyse = AnalyseServiceImpl.getInstance().getAnalyseByIdAnalyse(r.getAnalyse().getIdAnalyse());

			Prelevement prelevement = PrelevementServiceImpl.getInstance().getPrelevementById(analyse.getPrelevement().getIdPrelevement());
			Personne personne = PersonneServiceImpl.getInstance().getPersonneById(prelevement.getPersonne().getIdPersonne());
			RenduBiomol rbm = ResultatServiceImpl.getInstance().getRenduBioMolByIdResultat(r.getIdResultat());
			Puce puce = PuceServiceImpl.getInstance().getPuceByid(rbm.getPuce().getIdPuce());
			String repResultat = "";
			if (Character.isDigit(prelevement.getNumeroPrelevement().charAt(1))) {
				repResultat = ApplicationContexte.REPERTOIRE_RESULTAT + "activité 20" + prelevement.getNumeroPrelevement().substring(1, 3) + "\\" + prelevement.getNumeroPrelevement().substring(0, 1) + "\\";
			} else {
				if (Character.isDigit(prelevement.getNumeroPrelevement().charAt(2))) {
					repResultat = ApplicationContexte.REPERTOIRE_RESULTAT + "activité 20" + prelevement.getNumeroPrelevement().substring(2, 4) + "\\" + prelevement.getNumeroPrelevement().substring(0, 2) + "\\";
				}
			}
			// Champ dateExt =
			// PrelevementServiceImpl.getInstance().getChampByTypeAndIdObjet("dateExtraction",
			// "Prel-" + prelevement.getIdPrelevement());
			Champ typeADN = PrelevementServiceImpl.getInstance().getChampByTypeAndIdObjet("tTypeADN", "Prel-" + prelevement.getIdPrelevement());
			SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yyyy");

			// 2) Create Java model context
			IContext context = report.createContext();
			context.put("personne", personne);

			if (prelevement.getSecteur().getLibelle().equals(ApplicationContexte.SECTEUR_PUCE_PRENATAL)) {
				Champ cddg = PrelevementServiceImpl.getInstance().getChampByTypeAndIdObjet("dateDG", "Prel-" + prelevement.getIdPrelevement());
				Date ddg = null;
				if (cddg != null) {
					SimpleDateFormat formater = new SimpleDateFormat("yyyy-MM-dd");

					try {
						ddg = formater.parse(cddg.getValeur());
					} catch (ParseException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
				if (ddg != null) {
					context.put("dateNaissance", formatter.format(personne.getDateNaissance()) + "\r\nDate de début de grossesse : " + formatter.format(ddg));
				} else {
					context.put("dateNaissance", formatter.format(personne.getDateNaissance()) + "\r\nDate de début de grossesse : à compléter");
				}
			} else {
				context.put("dateNaissance", formatter.format(personne.getDateNaissance()));
			}

			if (typeADN != null) {
				context.put("tTypeADN", typeADN.getValeur() + " d'ADN");
			} else {
				context.put("tTypeADN", "Extraction d'ADN");
			}
			// if (dateExt != null) {
			// Date de = null;
			// if (dateExt != null) {
			// SimpleDateFormat formater = new SimpleDateFormat("yyyy-MM-dd");
			//
			// try {
			// de = formater.parse(dateExt.getValeur());
			// } catch (ParseException e) {
			// // TODO Auto-generated catch block
			// e.printStackTrace();
			// }
			// }
			// context.put("dateExtraction", formatter.format(de));
			// } else {
			// context.put("dateExtraction", "NON ENREGISTREE");
			// }

			String dateRendu;
			if (r != null && r.getDateRendu() != null) {
				dateRendu = formatter.format(r.getDateRendu());
			} else if (rbm != null && rbm.getDateRedaction() != null) {
				dateRendu = formatter.format(rbm.getDateRedaction());
			} else {
				dateRendu = formatter.format(new Date());
			}
			context.put("dateRendu", dateRendu);

			if (puce.getDateReunion() != null) {
				context.put("dateReception", formatter.format(puce.getDateReunion()));
			} else {
				if (puce.getDateRelecture() != null) {
					context.put("dateReception", formatter.format(puce.getDateRelecture()));
				}
			}
			if (prelevement.getDatePrelevement() == null) {
				context.put("datePrelevement", formatter.format(prelevement.getDateReception()));
			} else {
				context.put("datePrelevement", formatter.format(prelevement.getDatePrelevement()));
			}
			String oldtp = null;
			if (prelevement.getSecteur().getLibelle().equals(ApplicationContexte.SECTEUR_PUCE_PRENATAL)) {
				if (prelevement.getTypePrelevement().getLibelle().contains("mniotique")) {
					oldtp = (prelevement.getTypePrelevement().getLibelle());
					prelevement.getTypePrelevement().setLibelle("ADN extrait de Liquide Amniotique natif par le laboratoire de cytogénétique du CHU de Montpellier");
				}
			}
			if (prelevement.getTypePrelevement().getLibelle().contains("ang")) {
				oldtp = (prelevement.getTypePrelevement().getLibelle());
				prelevement.getTypePrelevement().setLibelle("ADN extrait de sang par le laboratoire de cytogénétique du CHU de Montpellier");
			}
			context.put("prelevement", prelevement);
			r.getSignataire().setNom(r.getSignataire().getNom().toUpperCase());
			rbm.getVerificateur().setNom(rbm.getVerificateur().getNom().toUpperCase());
			context.put("resultat", r);
			context.put("renduBiomol", rbm);

			List<VerifBiomolDoc> verifBiomolDocs = new ArrayList<VerifBiomolDoc>();
			if (rbm != null) {
				List<VerifBiomol> verifBiomols = ResultatServiceImpl.getInstance().getVerifBiomolByRenduBiomol(rbm.getIdRenduBioMol());
				int i = 1;
				for (VerifBiomol verifBiomol : verifBiomols) {
					verifBiomolDocs.add(new VerifBiomolDoc(i, verifBiomol, prelevement.getSecteur().getLibelle()));
					i++;
				}
			}
			context.put("verifBiomolDocs", verifBiomolDocs);
			context.put("analyse", analyse);

			if (!r.getCommentaire().contains("a permis de confirmer")) {
				context.put("attention", "1- Résultats strictement confidentiels ne pouvant être communiqués qu'au patient dans le cadre d'une consultation génétique.\r\n2- Toute analyse de génétique moléculaire comporte un risque d'erreur qui doit être expliqué aux patients et accepté.");
			} else {
				context.put(
						"attention",
						"1- Résultats ne permettant pas de borner le réarrangement et de préciser les points de cassure.\r\n2- Résultats ne permettant pas de conclure que cette anomalie est responsable du phénotype.\r\n3- Résultats strictement confidentiels ne pouvant être communiqués qu'au patient dans le cadre d'une consultation génétique.\r\n4- Toute analyse de génétique moléculaire comporte un risque d'erreur qui doit être expliqué aux patients et accepté.");
			}

			if (prelevement.getPrescripteur() != null) {
				context.put("prescripteur", prelevement.getPrescripteur());
				File fileout = new File(repResultat + prelevement.getNumeroPrelevement() + "_" + personne.getNom() + "_" + personne.getPrenom() + "_biomol" + r.getAnalyse().getIdAnalyse() + "_resultat" + r.getIdResultat() + "_" + dateRendu + "_" + prelevement.getPrescripteur().getNom() + ".docx");
				if (fileout.exists()) {
					creer = MessageDialog.openConfirm(Display.getCurrent().getActiveShell(), "Fichier existant", "Le fichier " + fileout.getName() + " existe déjà souhaitez vous l'écraser?");
				}
				if (creer) {
					fileout.setWritable(true);
					OutputStream out = new FileOutputStream(fileout);
					report.process(context, out);
					if (fileout.exists()) {
						nomFichierout += fileout.getName() + "#";
					}
				}
			}
			if (prelevement.getPrescripteur2() != null) {
				context.put("prescripteur", prelevement.getPrescripteur2());
				boolean creer2 = true;
				File fileout2 = new File(repResultat + prelevement.getNumeroPrelevement() + "_" + personne.getNom() + "_" + personne.getPrenom() + "_biomol" + r.getAnalyse().getIdAnalyse() + "_resultat" + r.getIdResultat() + "_" + dateRendu + "_" + prelevement.getPrescripteur2().getNom() + ".docx");
				if (fileout2.exists()) {
					creer2 = MessageDialog.openConfirm(Display.getCurrent().getActiveShell(), "Fichier existant", "Le fichier " + fileout2.getName() + " existe déjà souhaitez vous l'écraser?");
				}
				if (creer2) {
					fileout2.setWritable(true);
					OutputStream out2 = new FileOutputStream(fileout2);
					report.process(context, out2);
					if (fileout2.exists()) {
						nomFichierout += fileout2.getName() + "#";
					}
				}
			}

			if (prelevement.getPrescripteur3() != null) {
				context.put("prescripteur", prelevement.getPrescripteur3());
				boolean creer3 = true;
				File fileout3 = new File(repResultat + prelevement.getNumeroPrelevement() + "_" + personne.getNom() + "_" + personne.getPrenom() + "_biomol" + r.getAnalyse().getIdAnalyse() + "_resultat" + r.getIdResultat() + "_" + dateRendu + "_" + prelevement.getPrescripteur3().getNom() + ".docx");
				if (fileout3.exists()) {
					creer3 = MessageDialog.openConfirm(Display.getCurrent().getActiveShell(), "Fichier existant", "Le fichier " + fileout3.getName() + " existe déjà souhaitez vous l'écraser?");
				}
				if (creer3) {
					fileout3.setWritable(true);
					OutputStream out3 = new FileOutputStream(fileout3);
					report.process(context, out3);
					if (fileout3.exists()) {
						nomFichierout += fileout3.getName() + "#";
					}
				}
			}

			if (prelevement.getNomPrenomAutrePresc() != null && !prelevement.getNomPrenomAutrePresc().isEmpty()) {
				boolean creer4 = true;
				File fileout4 = new File(repResultat + prelevement.getNumeroPrelevement() + "_" + personne.getNom() + "_" + personne.getPrenom() + "_biomol" + r.getAnalyse().getIdAnalyse() + "_resultat" + r.getIdResultat() + "_" + dateRendu + "_" + prelevement.getNomPrenomAutrePresc() + ".docx");
				if (fileout4.exists()) {
					creer4 = MessageDialog.openConfirm(Display.getCurrent().getActiveShell(), "Fichier existant", "Le fichier " + fileout4.getName() + " existe déjà souhaitez vous l'écraser?");
				}
				if (creer4) {
					Utilisateur prescAutre = new Utilisateur();
					prescAutre.setNom(prelevement.getNomPrenomAutrePresc());
					prescAutre.setPrenom("");
					prescAutre.setAdresse("A compléter");
					context.put("prescripteur", prescAutre);
					fileout4.setWritable(true);
					OutputStream out4 = new FileOutputStream(fileout4);
					report.process(context, out4);
					if (fileout4.exists()) {
						nomFichierout += fileout4.getName() + "#";
					}
				}
			}
			if (oldtp != null) {
				prelevement.getTypePrelevement().setLibelle(oldtp);
			}
			in.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (XDocReportException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return nomFichierout;
	}
}
